// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

//
// Global variable definitions
//

uniform float fInnerRadius;
uniform float fKm4PI;
uniform float fKmESun;
uniform float fKr4PI;
uniform float fKrESun;
uniform float fOuterRadius;
uniform float fScale;
uniform float fScaleOverScaleDepth;
uniform vec4 fvCameraPos;
uniform vec3 fvInvWavelengths;
uniform vec4 fvLightPos;
uniform mat4 matWorldViewProjection;

//
// Function definitions
//

float scale( in float fCos ) {
    float x;

    x = (1.00000 - fCos);
    return (0.250000 * exp( (-0.00287000 + (x * (0.459000 + (x * (3.83000 + (x * (-6.80000 + (x * 5.25000)))))))) ));
}


void main() {
    vec3 v3Pos;
    vec3 v3Ray;
    float fFar;
    vec3 v3Start;
    float fStartAngle;
    float fStartDepth;
    float fStartOffset;
    float fSampleLength;
    float fScaledLength;
    vec3 v3SampleRay;
    vec3 v3SamplePoint;
    vec3 v3FrontColor = vec3( 0.00000, 0.00000, 0.00000);
    int i;
    float fHeight;
    float fDepth;
    float fLightAngle;
    float fCameraAngle;
    float fScatter;
    vec3 v3Attenuate;

    // Get the ray from the camera to the vertex and its length
    v3Pos = gl_Vertex.xyz ;
    v3Ray = (v3Pos - vec3( fvCameraPos));
    fFar = length( v3Ray );
    v3Ray /= fFar;
    
    // calculate the rays starting and end-points through the atmosphere
    v3Start = vec3( fvCameraPos);
    
    fStartAngle = (dot( v3Ray, v3Start) / fOuterRadius);
    fStartDepth = exp( -4.00000 );
    fStartOffset = (fStartDepth * scale( fStartAngle));
    
    // scattering loop variables
    fSampleLength = (fFar / 3.00000);
    fScaledLength = (fSampleLength * fScale);
    v3SampleRay = (v3Ray * fSampleLength);
    v3SamplePoint = (v3Start + (v3SampleRay * 0.500000));
    
    // loop through sample rays
    for (i = 0; (i < 3); ( i++ )) {
        fHeight = length( v3SamplePoint );
        fDepth = exp( (fScaleOverScaleDepth * (fInnerRadius - fHeight)) );
        fLightAngle = (dot( fvLightPos.xyz , v3SamplePoint) / fHeight);
        fCameraAngle = (dot( v3Ray, v3SamplePoint) / fHeight);
        fScatter = (fStartOffset + (fDepth * (scale( fLightAngle) - scale( fCameraAngle))));
        v3Attenuate = exp( (( -fScatter ) * ((fvInvWavelengths * fKr4PI) + fKm4PI)) );
        v3FrontColor += (v3Attenuate * (fDepth * fScaledLength));
        v3SamplePoint += v3SampleRay;
    }
    gl_Position = vec4( matWorldViewProjection * vec4( v3Pos, 1.0000) );
    gl_TexCoord[0] = vec4( (v3FrontColor * (fvInvWavelengths * fKrESun)), 1.00000);
    gl_TexCoord[1] = vec4( (v3FrontColor * fKmESun), 1.0000);
    gl_TexCoord[2] = vec4( vec3(fvCameraPos) - v3Pos, 0.0);
}

